package org.nicocube.airain.utils.telnet;

import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketTimeoutException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

import javax.net.ServerSocketFactory;

import org.nicocube.airain.utils.server.Server;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;


public class TelnetServer implements Runnable {
	public static final Logger log = LoggerFactory.getLogger(TelnetServer.class);

	public static final String TelnetPortProperty = "telnet.port";
	
	private static final String WELCOME_MESSAGE = "\r\n--------------------------------------------------------\r\n%s Program Control session\r\nWelcome! Enter your commands...(? for help)\r\n";
	
	private int port;
	private Server server;
	private ExecutorService telnetExecutor;
	
	public TelnetServer(int port, Server server) {
		this.server = server;		
		this.port = port;
		telnetExecutor = Executors.newCachedThreadPool();
	}

	public void launch() {
		telnetExecutor.execute(this);
	}

	@Override
	public void run() {
		
		ServerSocket serverSocket = null;
		Socket socket = null;
		
		try {
			serverSocket = ServerSocketFactory.getDefault().createServerSocket(this.port);
			if (log.isInfoEnabled()) log.info("Telnet on port "+this.port);
			serverSocket.setSoTimeout(1000);
		}
		catch (IOException e1) {
			log.error("Error on Socket opening",e1);
		}
		
		while(!telnetExecutor.isShutdown()){
			try {
				socket = serverSocket.accept();
				if (socket != null) {
					try {
						NetworkConnection connection = new NetworkConnection(socket);
						connection.sendLine(String.format(WELCOME_MESSAGE, server.getName()));
						CommandInterpreter cid = new CommandInterpreter(this,new CommandBinder(server), connection);
						telnetExecutor.execute(cid);
					}
					catch (Exception e) {
						log.error("Error on creating CommandInterpreter",e);
					}
				}
			}
			catch (SocketTimeoutException e) {
				// This is not an error -» nothing to do
				//System.out.println("delai d'ecoute depasse");
			}
			catch (IOException e) {
				log.error("Error on Socket accepting",e);
			}
		}
		
		try {
			serverSocket.close();
		}
		catch (IOException e) {
			log.error("Error on Socket closing",e);
		}	
	}

	public boolean isStopped() {
		return telnetExecutor.isShutdown();
	}
	
	public void stop() {
		telnetExecutor.shutdown();
	}	

}
